﻿' Copyright (C) 2015 HTTPBuilder
'
' This program is free software: you can redistribute it and/or modify it under the +terms 
' of the GNU General Public License as published by the Free Software Foundation, either 
' version 3 of the License, or (at your option) any later version.

' This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
' without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
' See the GNU General Public License for more details.

' You should have received a copy of the GNU General Public License along with this program.
' If not, see http://www.gnu.org/licenses/. 

Imports HTTPBuilder.Engine
Imports HTTPBuilder.Controls

Public Class MainForm

    Private WithEvents TaskExecuter As HttpExecuter

#Region "Form Load"
    Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles Me.Load

        UrlTextBox.Text = Settings.DefaultUrl
        ResponseBodyTextBox.WordWrap = Settings.Wordwrap
        RequestBodyTextBox.WordWrap = Settings.Wordwrap

        KnownHeadersToolStripComboBox.Items.AddRange(
            KnownHeaders.List)

        ListViewHelper.SetGroupCollapse(ResponseHeadersListView, ListViewHelper.GroupState.COLLAPSIBLE)

    End Sub
#End Region

#Region "Toolstrip, menustrip method"
    Private Sub NewWindowToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles NewWindowToolStripMenuItem.Click
        Dim assemble = System.Reflection.Assembly.GetExecutingAssembly()
        Process.Start(assemble.Location)
    End Sub

    Private Sub ToolStripButton2_Click(sender As Object, e As EventArgs) Handles ToolStripButton2.Click
        DoCopy()
    End Sub

    Private Sub CopyToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles CopyToolStripMenuItem.Click
        DoCopy()
    End Sub

    Private Sub ExecuteToolStripButton_Click(sender As Object, e As EventArgs) Handles ExecuteToolStripButton.Click
        DoExecute()
    End Sub

    Private Sub ExitToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExitToolStripMenuItem.Click
        End
    End Sub

    Private Sub ExecuteToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExecuteToolStripMenuItem.Click
        DoExecute()
    End Sub

    Private Sub KnownHeadersToolStripComboBox_SelectedIndexChanged(sender As Object, e As EventArgs) Handles KnownHeadersToolStripComboBox.SelectedIndexChanged
        RequestHeadersTextBox.Text += String.Format("{0}: <value>", KnownHeadersToolStripComboBox.Text) + vbNewLine
        RequestHeadersTextBox.Focus()
        RequestHeadersTextBox.SelectionStart = RequestHeadersTextBox.Text.Length - 1
    End Sub

    Private Sub ResultListToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ResultListToolStripMenuItem.Click
        DoToggleViewResultList()
    End Sub

    Private Sub RequestToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles RequestToolStripMenuItem.Click
        DoToggleType()
    End Sub

    Private Sub ResponseToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ResponseToolStripMenuItem.Click
        DoToggleType()
    End Sub

    Private Sub AboutToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles AboutToolStripMenuItem.Click
        Dim aboutFrm As New AboutBoxForm
        aboutFrm.ShowDialog(Me)
    End Sub
#End Region

#Region "Private methods"
    Private Sub DoCopy()
        If TypeTabControl.SelectedIndex = 0 Then
            If RequestTabControl.SelectedIndex = 1 Then
                If Not String.IsNullOrEmpty(RequestHeadersTextBox.SelectedText) Then
                    Clipboard.SetText(RequestHeadersTextBox.SelectedText)
                End If
            End If
            If RequestTabControl.SelectedIndex = 2 Then
                If Not String.IsNullOrEmpty(RequestBodyTextBox.SelectedText) Then
                    Clipboard.SetText(RequestBodyTextBox.SelectedText)
                End If
            End If
        End If
        If TypeTabControl.SelectedIndex = 1 Then
            If ResponseTabControl.SelectedIndex = 0 Then
                Dim clipText As String = ""
                For Each o As ListViewItem In ResponseHeadersListView.SelectedItems
                    If Not String.IsNullOrEmpty(clipText) Then
                        clipText += vbNewLine
                    End If
                    clipText += (o.Text + ":").PadRight(25, " ") + If(o.SubItems.Count > 1, o.SubItems(1).Text, "")
                Next

                Clipboard.SetText(clipText)
            End If
            If ResponseTabControl.SelectedIndex = 1 Then
                If Not String.IsNullOrEmpty(ResponseBodyTextBox.SelectedText) Then
                    Clipboard.SetText(ResponseBodyTextBox.SelectedText)
                End If
            End If
        End If
    End Sub

    Private Function DoNew() As Boolean
        If MessageBox.Show("Do you wish to reset to default?", "HTTPBuilder", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) = Windows.Forms.DialogResult.Yes Then
            UrlTextBox.Text = "http://www.microsoft.com"
            RequestHeadersTextBox.Text = "User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)"
            RequestBodyTextBox.Text = ""
            TypeTabControl.SelectedIndex = 0
            RequestTabControl.SelectedIndex = 0
            ResponseTabControl.SelectedIndex = 0
            DoToggleType(False)
            ResultListView.Items.Clear()
            MethodComboBox.Text = "GET"

            Return True
        End If

        Return False
    End Function

    Private Sub DoExecute()
        If taskExecuter Is Nothing Then
            taskExecuter = New HttpExecuter
        End If
        taskExecuter.AllowRedirect = AutoRedirectCheckBox.Checked
        taskExecuter.SetContentLengthHeader = ContentLengthFixCheckBox.Checked

        ' update title bar
        Me.Text = String.Format("HTTPBuilder - {0}", UrlTextBox.Text)

        Cursor = Cursors.WaitCursor

        Dim status As ExecutionJob = Nothing
        Try
            status = TaskExecuter.Run(UrlTextBox.Text,
                                      MethodComboBox.Text,
                                      RequestBodyTextBox.Text,
                                      New HeaderCollection(RequestHeadersTextBox.Text))

            If Not status.IsError Then
                StatusStatusLabel.Text = "Execution completed OK"
                If status.ResponseDataType = ContentTypeEnum.Image Then
                    PictureBox1.Image = status.ResponseData
                Else
                    ResponseBodyTextBox.Text = status.ResponseData ' TODO: should be REsponseData
                End If
            Else
                StatusStatusLabel.Text = "Error."
                ResponseBodyTextBox.Text = status.ResponseData
            End If
        Catch ex As Exception
            ex = ex
        Finally
            AddToListView(status)
        End Try

        ExecutionTimeStatusLabel.Text = TaskExecuter.ExecutionTime.Milliseconds & "ms"

        If Settings.FocusResponseBody Then
            TypeTabControl.SelectedIndex = 1
            ResponseTabControl.SelectedIndex = 1
        End If

        Cursor = Cursors.Default
    End Sub

    Private Sub DoToggleType(Optional ByVal SelectTab As Boolean = True)
        If TypeTabControl.SelectedIndex = 1 Then
            If SelectTab Then TypeTabControl.SelectedIndex = 0
        Else
            If SelectTab Then TypeTabControl.SelectedIndex = 1
        End If

        RequestToolStripMenuItem.Checked = (TypeTabControl.SelectedIndex = 0)
        ResponseToolStripMenuItem.Checked = (TypeTabControl.SelectedIndex = 1)
    End Sub

    Private Sub DoToggleViewResultList()
        'If ResultListView.vis Then
        If SplitContainer1.Panel2Collapsed = True Then
            SplitContainer1.Panel2Collapsed = False
        Else
            SplitContainer1.Panel2Collapsed = True
        End If
        ResultListToolStripMenuItem.Checked = Not SplitContainer1.Panel2Collapsed
    End Sub
#End Region

#Region "Element methods"
    Private Sub RenderResponseListView(job As ExecutionJob)
        ResponseHeadersListView.Items.Clear()
        ResponseHeadersListView.Items.Add(GetSubListViewItem("Status Code", CInt(job.Status).ToString, ResponseHeadersListView.Groups(0)))
        ResponseHeadersListView.Items.Add(GetSubListViewItem("Status description", job.StatusDescription, ResponseHeadersListView.Groups(0)))
        ResponseHeadersListView.Items.Add(GetSubListViewItem("Method", job.Method.ToUpper, ResponseHeadersListView.Groups(0)))
        ResponseHeadersListView.Items.Add(GetSubListViewItem("Response Length", job.ResponseData.ToString.Length.ToString("0,0"), ResponseHeadersListView.Groups(0)))
        For Each headerKey As String In job.RequestHeaders.Keys
            ResponseHeadersListView.Items.Add(GetSubListViewItem(headerKey, job.RequestHeaders(headerKey), ResponseHeadersListView.Groups(1)))
        Next
        If job.ResponseHeaders IsNot Nothing AndAlso job.ResponseHeaders.Count > 0 Then
            For Each headerKey As String In job.ResponseHeaders.Keys
                ResponseHeadersListView.Items.Add(GetSubListViewItem(headerKey, job.ResponseHeaders(headerKey), ResponseHeadersListView.Groups(2)))
            Next
        End If
        If job.ResponseCookies IsNot Nothing AndAlso job.ResponseCookies.Count > 0 Then
            For Each cookie As Net.Cookie In job.ResponseCookies
                ResponseHeadersListView.Items.Add(GetSubListViewItem(cookie.Name, cookie.Value, ResponseHeadersListView.Groups(3)))
            Next
        End If
        ResponseHeadersListView.Items.Add(GetSubListViewItem("Duration", job.Time & "ms", ResponseHeadersListView.Groups(4)))
    End Sub

    Private Sub AddToListView(job As ExecutionJob)
        Dim itm As ListViewItem = New ListViewItem(job.TaskNo)
        itm.ImageIndex = IIf(job.IsError, 0, 1)
        itm.SubItems.Add(job.Status.ToString)
        itm.SubItems.Add(job.Uri.Scheme.ToUpper)
        itm.SubItems.Add(job.Url)
        itm.SubItems.Add(job.Time.ToString & "ms")
        ResultListView.Items.Insert(0, itm)

        RenderResponseListView(job)
    End Sub

    Private Function GetSubListViewItem(value As String, subValue As String, group As ListViewGroup) As ListViewItem
        Dim itm As ListViewItem = New ListViewItem(value)
        If group IsNot Nothing Then
            itm.Group = group
        End If
        'If bold Then
        '    itm.Font = New Font(itm.Font.FontFamily, itm.Font.Size, FontStyle.Bold)
        'End If
        If Not String.IsNullOrEmpty(subValue) Then
            itm.SubItems.Add(subValue)
        End If
        Return itm
    End Function
    Private Function GetSubListViewItem(value As String, subValue As String) As ListViewItem
        Return GetSubListViewItem(value, subValue, Nothing)
    End Function

    Private Sub RequestTabControl_Selected(sender As Object, e As TabControlEventArgs) Handles RequestTabControl.Selected
        If e.TabPageIndex = 1 Then
            KnownHeadersToolStripComboBox.Enabled = True
        Else
            KnownHeadersToolStripComboBox.Enabled = False
        End If
    End Sub

    Private Sub TypeTabControl_SelectedIndexChanged(sender As Object, e As EventArgs) Handles TypeTabControl.SelectedIndexChanged
        DoToggleType(False)

        If TypeTabControl.SelectedIndex = 0 AndAlso RequestTabControl.SelectedIndex = 1 Then
            KnownHeadersToolStripComboBox.Enabled = True
        Else
            KnownHeadersToolStripComboBox.Enabled = False
        End If
    End Sub

    Private Sub ClearListToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ClearListToolStripMenuItem.Click
        ResultListView.Items.Clear()
    End Sub

    Private Sub NewToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles NewToolStripMenuItem.Click
        DoNew()
    End Sub

    Private Sub NewJSonToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles NewJSonToolStripMenuItem.Click
        If DoNew() Then
            RequestHeadersTextBox.Text += vbNewLine + "Content-Type: Application/Json"
        End If
    End Sub

    Private Sub ToolStripButton1_Click(sender As Object, e As EventArgs) Handles ToolStripButton1.Click
        DoNew()
    End Sub
#End Region

    Private Sub OptionsToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OptionsToolStripMenuItem.Click
        Dim optionsFrm As OptionsForm = New OptionsForm
        optionsFrm.ShowDialog(Me)
    End Sub

    Private Sub JsonToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles JsonToolStripMenuItem.Click
        Dim currentText As String = ResponseBodyTextBox.Text
        Dim formatter As Extensability.IFormatter = New JsonFormatter(currentText)
        ResponseBodyTextBox.Text = formatter.Format
    End Sub

    Private Sub XMLToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles XMLToolStripMenuItem.Click
        Dim currentText As String = ResponseBodyTextBox.Text
        Dim formatter As Extensability.IFormatter = New XmlFormatter(currentText)
        ResponseBodyTextBox.Text = formatter.Format

    End Sub
End Class
